define('framework/dropdown/GillionDropDownDirectiveConstructor',['angular'], function (angular) {
    return function ($parse,$timeout,$document) {
        var RadioDropdown,CheckBoxDropdown,DropdownFactory;
        var extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
            hasProp = {}.hasOwnProperty;

        function BaseDropdown($scope, $attrs, $controller, $timeout, itemList) {
            this.$scope = $scope;
            this.$attrs = $attrs;
            this.$controller = $controller;
            this.$timeout = $timeout;
            this.itemList = !!itemList ? itemList : [];
            this.valueSeparator = $scope.valueSeparator || ',';
        };

        BaseDropdown.prototype.selectItem = function(item) {
            this.$scope.setModelValue(item.attrs.value);
            this.$scope.display=item.element.text();
            this.$scope.isShow=false;
            this.$scope.$apply();
        };
        //显示选择 用于回显
        BaseDropdown.prototype.showSelect = function(value) {
            var me = this;
            if(value){
                var display = me.itemList.filter(function(item){
                    return item.attrs.value == value;
                }).map(function(item){
                        return item.element.text();
                });
                me.$scope.display = display.join(me.valueSeparator);
            }else{
                me.$scope.display = '';
            }
        };

        BaseDropdown.prototype.refreshSelect = function(newValue) {
            var me = this;
            if(newValue){
                var display = me.itemList.filter(function(item){
                    item.unSelect();
                    return item.element.text() == newValue;
                }).map(function(item){
                    item.select();
                    return item.attrs.value;
                });
                me.$scope.setModelValue(display.join(me.valueSeparator));
            }else{
                me.$scope.setModelValue('');
            }
        };

        RadioDropdown = (function (superClass) {
            extend(RadioDropdown, superClass);

            function RadioDropdown($scope, $attrs, $controller, $timeout, itemList) {
                this.$scope = $scope;
                this.$attrs = $attrs;
                this.$controller = $controller;
                this.$timeout = $timeout;
                this.itemList = !!itemList ? itemList : [];
                RadioDropdown.__super__.constructor.call(this, this.$scope, this.$attrs, this.$controller, this.$timeout, this.itemList);
            };

            RadioDropdown.prototype.selectItem = function(item) {
                var selected = item.getSelect(),
                    me = this,
                    myScope = me.$scope;
                for(var i=0;i<this.itemList.length;i++){
                    var each = this.itemList[i];
                    each.unSelect();
                }
                if(selected){
                    myScope.setModelValue('');
                    myScope.display='';
                }else{
                    item.select();
                    myScope.setModelValue(item.attrs.value);
                    myScope.display=item.element.text();

                }
                myScope.isShow=false;
                myScope.$apply();

            };

            RadioDropdown.prototype.showSelect = function(value) {
                var me = this;
                if(value){
                    var display = me.itemList.filter(function(item){
                        item.unSelect();
                        return item.attrs.value == value;
                    }).map(function(item){
                        item.select();
                        return item.element.text();
                    });
                    me.$scope.display = display.join(me.valueSeparator);
                }else{
                    me.$scope.display = '';
                }
            };
            return RadioDropdown;
        })(BaseDropdown);

        /*复选框列表 */
        CheckBoxDropdown = (function(superClass) {
            extend(CheckBoxDropdown, superClass);

            function CheckBoxDropdown($scope, $attrs, $controller, $timeout, itemList) {
                var self;
                this.$scope = $scope;
                this.$attrs = $attrs;
                this.$timeout = $timeout;
                this.itemList = !!itemList ? itemList : [];
                CheckBoxDropdown.__super__.constructor.call(this, this.$scope, this.$attrs, this.$controller, this.$timeout, this.itemList);
                self = this;
            };

            CheckBoxDropdown.prototype.selectItem = function(item) {
                var displayArray = [],
                    submitArray = [],
                    me = this,
                    myScope = this.$scope,
                    length = this.itemList.length;
                item.getSelect()?item.unSelect():item.select();
                for(var i=0;i<length;i++){
                    var each = me.itemList[i];
                    if(each.getSelect()){
                        displayArray.push(each.element.text());
                        submitArray.push(each.attrs.value);
                    }
                }
                myScope.setModelValue(submitArray.join(me.valueSeparator));
                myScope.display=displayArray.join(me.valueSeparator);
                myScope.$apply();
            };

            CheckBoxDropdown.prototype.showSelect = function(value) {
                var me =this,
                    myScope = me.$scope,
                    valArray,
                    display,
                    result;
                if(value){
                    valArray = value.split(me.valueSeparator);
                    display = this.itemList.filter(function(item){
                        item.unSelect();
                        result = valArray.filter(function(val){
                            return val == item.attrs.value;
                        });
                        return result.length>0;
                    }).map(function(item){
                        item.select();
                        return item.element.text();
                    });
                    myScope.display = display.join(me.valueSeparator);
                }else{
                    myScope.display = '';
                }
            };

            CheckBoxDropdown.prototype.showSelect = function(value) {
                var me =this,
                    myScope = me.$scope,
                    valArray,
                    display,
                    result;
                if(value){
                    valArray = value.split(me.valueSeparator);
                    display = this.itemList.filter(function(item){
                        item.unSelect();
                    result = valArray.filter(function(val){
                            return val == item.attrs.value;
                        });
                        return result.length>0;
                    }).map(function(item){
                        item.select();
                        return item.element.text();
                    });
                    myScope.display = display.join(me.valueSeparator);
                }else{
                    myScope.display = '';
                }
            };

            CheckBoxDropdown.prototype.refreshSelect = function(newValue) {
                var me = this;
                if(newValue){
                    var newValueArray = newValue.split(me.valueSeparator);

                    var display = me.itemList.filter(function(item){
                        item.unSelect();
                        return newValueArray.filter(function(val){
                            return val==item.element.text();
                        }).length>0;
                    }).map(function(item){
                        item.select();
                        return item.attrs.value;
                    });
                    me.$scope.setModelValue(display.join(me.valueSeparator));
                }else{
                    me.$scope.setModelValue('');
                }
            };

            return CheckBoxDropdown;

        })(BaseDropdown);

        DropdownFactory = {
            create:function ( $scope, $attrs, $controller, $timeout){

            var simpleList ;
            switch ($scope.listType) {
                case "single":
                    simpleList = new RadioDropdown($scope, $attrs, $controller, $timeout);
                    break;
                case "multi":
                    simpleList = new CheckBoxDropdown($scope, $attrs, $controller, $timeout);
                    break;
                default:
                    simpleList = new BaseDropdown($scope, $attrs, $controller, $timeout);
                    break;
            }
            return simpleList;
            }
        };

            return {
            scope:{
                source: '=',
                valueProp: '@',
                displayExpress: '@',
                valueSeparator:'@',
                addEvent:'&',
                listType:'@',
                placeholder:'@',
                disabled:'@'
            },
            replace:true,
            transclude: true,
            require:['^?ngModel','?gDropdown'],
            template:'<div ng-cloak class="form-dorpdown"><input type="text" class="form-text"  ng-disabled ="disabled" ng-model="display" value="请选择" >'+
            '<a type="button" ng-click="showDropDown()" class="btn dropdown-toggle"> <i class="fi fi-caret"></i> </a>'+
            '<ul ng-show="isShow" class="dropdown-menu" style="display: block;">'+
            '<g-dropitem ng-repeat="element in source"  value="{{valueGetter(element)}}" text="{{displayGetter(element)}}" ></g-dropitem>' +
            '<li ng-show="addShow" class="form-dorpdown-additem" ng-click="addEvent()"><button class="btn"><i class="fi fi-add-circle"></i></button></li></ul>',
            restrict: 'E',
            controller:function($scope, $element, $attrs){
                return DropdownFactory.create( $scope, $attrs, this, $timeout);
            },
            compile:function(tElement, tAttrs,transclude){
                tElement.find("input").attr('ng-change', 'refreshSelect()');
                return function (scope, element,attrs,controllers) {
                    /*初始化参数*/
                    var ngModel = controllers[0],
                        myController = controllers[1],
                        keyIndex = -1,
                        timer;
                    scope.isShow =false;
                    scope.scrollY = false;
                    scope.displayName = '';
                    scope.refreshSelect = function(){
                        var newVal = element.find("input").val();
                        myController.refreshSelect(newVal);
                    }
                    //scope.disabled = attrs.disabled !==undefined?true:false;
                    //下拉框显示隐藏
                    scope.showDropDown = function(){
                        if(scope.disabled!=='disabled'){
                            scope.isShow = !scope.isShow;
                            element.find("input")[0].focus();
                        }
                    };
                    //手动添加的子指令
                    transclude(scope, function (clone) {
                        element.find("ul").append(clone);
                    });

                    //宽度
                    if (angular.isDefined(attrs.width)) {
                        element.css("width", attrs.width);
                    }else{
                        element.css("width", "300px");
                    }
                    if (angular.isDefined(attrs.cssClass)) {
                        element.addClass(attrs.cssClass);
                    }
                    scope.setModelValue = function(val){
                        if(ngModel) {
                            ngModel.$setViewValue(val);
                        }
                    };
                    scope.getModelValue = function(){
                        if(ngModel) {
                            return ngModel.$modelValue;
                        }
                    }
                    if(ngModel){
                        ngModel.$formatters.push(function(value){
                            ngModel.$setViewValue(value);
                            myController.showSelect(value);
                        });
                    }

                    if(attrs.addEvent) {
                        scope.addShow = true;
                    }
                    var returnParamFn = function (arg) {
                        return arg;
                    };
                    var valueGetter = !!scope.valueProp ? $parse(scope.valueProp) : returnParamFn;
                    scope.displayGetter = !!scope.displayExpress ? $parse(scope.displayExpress) : returnParamFn;
                    scope.valueGetter = valueGetter;

                    if(scope.placeholder){
                        element.find("input").attr("placeholder",scope.placeholder);
                    }

                    //点击隐藏
                    $document.on('click', function (event) {
                        if (element.find(event.srcElement || event.target).length === 0) {
                            scope.isShow =false;
                            myController.showSelect(ngModel.$modelValue);
                            scope.$digest();
                        }
                    });
                    scope.itemList = myController.itemList;
                    scope.$watchCollection("itemList",function(){
                        myController.showSelect(ngModel.$modelValue);
                    });
                    //输入框键盘输入事件
                    element.find("input").on("keyup", function (e) {
                        var currKey = e.keyCode || e.which || e.charCode,
                            keyLength = myController.itemList.length;
                        switch (currKey) {

                            //方向上键
                            case 38:
                                var keyNextIndex = keyIndex<0?keyIndex+keyLength:keyIndex;
                                keyIndex = keyIndex<0?keyIndex+keyLength:(keyIndex-1+keyLength)%keyLength;
                                myController.itemList[keyIndex].addSelectStyle();
                                myController.itemList[keyNextIndex].removeSelectStyle();
                                break;
                            //方向下键
                            case 40:
                                var keyLastIndex = keyIndex<0?keyIndex+keyLength:keyIndex;
                                keyIndex = (keyIndex+1)%keyLength;
                                myController.itemList[keyIndex].addSelectStyle();
                                myController.itemList[keyLastIndex].removeSelectStyle();
                                break;
                            //空格键
                            case 32:
                                var item = myController.itemList[keyIndex];
                                if(item){
                                    item.element[0].click();
                                }
                                return false;
                                break;
                            //回车键
                            case 13:
                                break;
                            default:

                                break;
                        }
                    });
                }
            }
        }
    }
});